namespace Crux.Core.Dapper.SqlGenerator;
public partial class SqlGenerator<TEntity>
    where TEntity : class
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    public virtual SqlQuery GetCount(Expression<Func<TEntity, bool>>? predicate, bool ignoreFilter = false, params Expression<Func<TEntity, object>>[] includes)
    {
        var sqlQuery = new SqlQuery(this.Provider);

        sqlQuery.SqlBuilder
            .Append("SELECT COUNT(*)");

        if (includes.Any())
        {
            var joinsBuilder = AppendJoinToSelect(sqlQuery, true, includes);
            sqlQuery.SqlBuilder
                .Append(" FROM ")
                .Append(TableName)
                .Append(" ");

            sqlQuery.SqlBuilder.Append(joinsBuilder);
        }
        else
        {
            sqlQuery.SqlBuilder
                .Append(" FROM ")
                .Append(TableName)
                .Append(" ");
        }

        AppendWherePredicateQuery(sqlQuery, predicate, QueryType.Select, ignoreFilter);

        return sqlQuery;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="distinctField"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    public virtual SqlQuery GetCount(
        Expression<Func<TEntity, bool>>? predicate,
        Expression<Func<TEntity, object>> distinctField,
        bool ignoreFilter = false,
        params Expression<Func<TEntity, object>>[] includes)
    {
        var propertyName = ExpressionHelper.GetPropertyName(distinctField);
        var property = SqlProperties.First(x => x.PropertyName == propertyName);
        var sqlQuery = InitBuilderCountWithDistinct(property);

        if (includes.Any())
        {
            var joinsBuilder = AppendJoinToSelect(sqlQuery, true, includes);
            sqlQuery.SqlBuilder
                .Append(" FROM ")
                .Append(TableName)
                .Append(" ");

            sqlQuery.SqlBuilder.Append(joinsBuilder);
        }
        else
        {
            sqlQuery.SqlBuilder
                .Append(" FROM ")
                .Append(TableName)
                .Append(" ");
        }

        AppendWherePredicateQuery(sqlQuery, predicate, QueryType.Select, ignoreFilter);

        return sqlQuery;
    }

    private SqlQuery InitBuilderCountWithDistinct(SqlPropertyMetadata sqlProperty)
    {
        var query = new SqlQuery(this.Provider);
        query.SqlBuilder.Append("SELECT COUNT(DISTINCT ");

        query.SqlBuilder
            .Append(TableName)
            .Append(".")
            .Append(sqlProperty.ColumnName)
            .Append(")");

        if (sqlProperty.Alias is not null)
            query.SqlBuilder
                .Append(" AS ")
                .Append(sqlProperty.PropertyName);

        return query;
    }
}